package com.bmps.springcloud.insuredmicroservice.service.calculate;

import com.bmps.springcloud.insuredmicroservice.model.accept.InsureaccModel;
import com.bmps.springcloud.insuredmicroservice.model.accept.LcPolModel;
import com.bmps.springcloud.insuredmicroservice.repository.calculate.coresystem.AccountValueRepository;
import com.bmps.springcloud.insuredmicroservice.util.calculate.CalculateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * description:
 *
 * @author jackdaw
 * @date 2019-12-17 18:14
 */

@Service
public class AccountValueServiceImpl implements AccountValueService {

    private Logger logger = LoggerFactory.getLogger(AccountValueServiceImpl.class);
    private final AccountValueRepository accountValueRepository;

    public AccountValueServiceImpl(AccountValueRepository accountValueRepository) {
        this.accountValueRepository = accountValueRepository;
    }

    @Override
    public BigDecimal calculateInvestment(String contNo) {
        BigDecimal result = accountValueRepository.queryInvestment(contNo);
        if (result == null) {
            return BigDecimal.valueOf(-1);
        }
        return result;
    }

    @Override
    public BigDecimal calculateUniversal(String contNo) {
        Date current = getCurrentDate();
        BigDecimal total = BigDecimal.valueOf(0);
        double interest;
        //查询账户和部分保单信息
        List<InsureaccModel> insureaccModels = accountValueRepository.queryUniversal(contNo);
        for (InsureaccModel insureaccModel : insureaccModels) {
            double currentAccValue = 0;
            String polNo = insureaccModel.getPolNo();
            String insuaccno = insureaccModel.getInsuaccno();
            Date balaDate = insureaccModel.getBalaDate();
            String riskCode = insureaccModel.getRiskCode();
            Date cvalidate = insureaccModel.getCvalidate();
            //查询利率指针
            List<Map<String, Object>> pointers = accountValueRepository.queryPointerCodeAndBalaType(riskCode, cvalidate);
            if (CollectionUtils.isEmpty(pointers) || pointers.size() != 1) {
                logger.error("利率指针信息查询失败或没有对应的利率指针信息");
                return BigDecimal.valueOf(-1);
            }
            //查询指针最大公布利率止期
            Date maxRateEndDate = accountValueRepository.queryMaxRateEndDate(pointers.get(0).get("pointercode").toString());
            boolean hasDealRate = false;
            if (maxRateEndDate != null && maxRateEndDate.compareTo(getCurrentDate()) >= 0) {
                hasDealRate = true;
            }
            if (current.compareTo(balaDate) < 0) {
                total = total.add(accountValueRepository.queryClassMoneyBala(polNo, insuaccno, balaDate));
                continue;
            }
            //账户管理费信息是否补充 select * from LCInsureAccFee where polno='' and insuaccno='' 判断不能为null
            //子账户金额
            BigDecimal money = accountValueRepository.queryClassMoney(polNo, insuaccno, balaDate);
            if (money == null) {
                return BigDecimal.valueOf(-1);
            }
            currentAccValue = money.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            double sumAccValueInterest = 0;
            double sumGurantInterest = 0;
            double accValueInterest = 0;
            double gurantInterest = 0;
            if (hasDealRate) {
                //查询利率
                List<Map<String, Object>> rateBalaInfos = accountValueRepository.queryBalaRate(balaDate, getCurrentDate(), riskCode, cvalidate);
                List<Map<String, Object>> rateGurantInfos = accountValueRepository.queryGurantRate(balaDate, getCurrentDate(), riskCode, cvalidate);
                if (StringUtils.equals("0", pointers.get(0).get("balatype").toString())) {

                    if (CollectionUtils.isNotEmpty(rateBalaInfos)) {
                        accValueInterest = currentAccValue * (CalculateUtil.getMultiResultRateMS(rateBalaInfos, "C", "Y", balaDate, getCurrentDate()));
                    }
                    if (CollectionUtils.isNotEmpty(rateGurantInfos)) {
                        gurantInterest = currentAccValue * (CalculateUtil.getMultiResultRateMS(rateGurantInfos, "C", "Y", balaDate, getCurrentDate()));
                    }

                    sumAccValueInterest += accValueInterest;
                    sumGurantInterest += gurantInterest;
                } else if (StringUtils.equals("1", pointers.get(0).get("balatype").toString())) {
                    Double moneyStand = accountValueRepository.queryStandMoney(polNo, insuaccno, balaDate);
                    if (moneyStand == null) {
                        return BigDecimal.valueOf(-1);
                    }
                    if (CollectionUtils.isNotEmpty(rateBalaInfos)) {
                        accValueInterest = moneyStand * (CalculateUtil.getMultiResultRateMS(rateBalaInfos, "S", "Y", balaDate, getCurrentDate()));
                    }
                    if (CollectionUtils.isNotEmpty(rateGurantInfos)) {
                        gurantInterest = moneyStand * (CalculateUtil.getMultiResultRateMS(rateGurantInfos, "S", "Y", balaDate, getCurrentDate()));
                    }
                    sumAccValueInterest += accValueInterest;
                    sumGurantInterest += gurantInterest;
                } else {
                    return BigDecimal.valueOf(-1);
                }
            }
            //获取本月交易金额
            List<Map<String, Object>> monthTraces = accountValueRepository.queryMonthMoney(polNo, insuaccno, current, balaDate);
            if (monthTraces == null) {
                return BigDecimal.valueOf(-1);
            }
            double getMoney = 0;
            for (Map<String, Object> monthTrace : monthTraces) {
                double monthMoney = (double) monthTrace.get("money");
                Date payDate = (Date) monthTrace.get("paydate");
                if (hasDealRate) {
                    //查询利率
                    List<Map<String, Object>> rateBalaInfos = accountValueRepository.queryBalaRate(payDate, getCurrentDate(), riskCode, cvalidate);
                    List<Map<String, Object>> rateGurantInfos = accountValueRepository.queryGurantRate(payDate, getCurrentDate(), riskCode, cvalidate);
                    if (StringUtils.equals("0", pointers.get(0).get("balatype").toString())) {

                        if (CollectionUtils.isNotEmpty(rateBalaInfos)) {
                            accValueInterest = monthMoney * (CalculateUtil.getMultiResultRateMS(rateBalaInfos, "C", "Y", payDate, current));
                        }
                        if (CollectionUtils.isNotEmpty(rateGurantInfos)) {
                            gurantInterest = monthMoney * (CalculateUtil.getMultiResultRateMS(rateGurantInfos, "C", "Y", payDate, current));
                        }
                        sumAccValueInterest += accValueInterest;
                        sumGurantInterest += gurantInterest;
                    } else if (StringUtils.equals("1", pointers.get(0).get("balatype").toString())) {

                        if (CollectionUtils.isNotEmpty(rateBalaInfos)) {
                            accValueInterest = monthMoney * (CalculateUtil.getMultiResultRateMS(rateBalaInfos, "S", "Y", payDate, current));
                        }
                        if (CollectionUtils.isNotEmpty(rateBalaInfos)) {
                            gurantInterest = monthMoney * (CalculateUtil.getMultiResultRateMS(rateGurantInfos, "S", "Y", payDate, current));
                        }
                        sumAccValueInterest += accValueInterest;
                        sumGurantInterest += gurantInterest;
                    }
                }
                getMoney += monthMoney;
            }
            currentAccValue += getMoney;
            interest = sumAccValueInterest;
            if (sumGurantInterest > sumAccValueInterest) {
                interest = sumGurantInterest;
            }
            currentAccValue += interest;
            if (currentAccValue < 0) {
                return BigDecimal.valueOf(-1);
            }
            Double moreMoney = accountValueRepository.queryMoreMoney(polNo, insuaccno);
            if (moreMoney == null) {
                return BigDecimal.valueOf(-1);
            }
            currentAccValue += moreMoney;
            total = total.add(BigDecimal.valueOf(currentAccValue));
        }

        return total;
    }

    @Override
    public LcPolModel queryMainPol(String prtNo) {

        return accountValueRepository.queryMainPol(prtNo);
    }

    private Date getCurrentDate() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return date;
    }

    public static void main(String[] args) {

    }
}
